package com.paic.icore.test.demo.action;

import com.google.common.collect.Lists;
import com.paic.icore.test.demo.entity.Country;
import com.paic.icore.test.demo.entity.User;
import com.paic.icore.test.demo.lock.RedissonLockUtil;
import com.paic.icore.test.demo.service.CountryService;
import com.paic.icore.test.demo.service.UserService;
import com.paic.icore.test.demo.util.SqlHelper;
import com.paic.icore.test.demo.vo.TimeRange;
import com.paic.icore.test.demo.vo.TimeSlot;
import com.sensetime.iva.whale.video.core.dao.VideoResourceMapper;
import com.sensetime.iva.whale.video.easyexcel.entity.VideoResource;
import io.swagger.annotations.*;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Api(description = "视频源对外api接口")
@RestController
public class DemoController {

    private static final Logger logger = LoggerFactory.getLogger(DemoController.class);

    @Autowired
    private CountryService countryService;

    @Autowired
    private UserService userService;

    @Autowired
    private RedissonLockUtil redissonLockUtil;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private VideoResourceMapper videoResourceMapper;

    @Autowired
    @Resource
    private SqlSessionFactory sqlSessionFactory;

    @ApiOperation(value = "视频源导入", notes = "视频源导入", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE, extensions = {
            @Extension(name = "version", properties = @ExtensionProperty(name = "since", value = "4.0"))})
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    public String uploadExcel(@ApiParam(value = "视频源导入文件", required = true) @RequestParam(value = "file", required = true) MultipartFile file) throws Exception {
        System.out.println(file);
        logger.info("Import video resource.|Param:file:{},", file.getOriginalFilename());
        return "";
    }

    @ApiOperation(value = "描述value", notes = "描述notes", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, extensions = {
            @Extension(name = "version", properties = @ExtensionProperty(name = "since", value = "4.0"))})
    @GetMapping("/der")
    public Long der() {
        String key = String.format("test:incre");
        redisTemplate.delete(key);
        Long max = null;
        ExecutorService IMPORT_THREAD_POOL = Executors.newFixedThreadPool(10);
        List<Integer> lists = Lists.newArrayList();
        for (int i = 0; i < 1000; i++) {
//            max = redisTemplate.opsForValue().increment(key, 1L);
            lists.add(i);
        }
        long begin = System.currentTimeMillis();
        CompletableFuture[] completableFutures = lists.stream().map(r -> CompletableFuture.runAsync(() -> {
            System.out.println(getData(key));
        }, IMPORT_THREAD_POOL)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(completableFutures).join();
        long end = System.currentTimeMillis();
        System.out.println("date cost " + (end - begin));
        return max;
    }

    private String getData(String key) {
        Object o = redisTemplate.opsForValue().get(key);
        if (o == null) {
            synchronized (this) {
                Object o1 = redisTemplate.opsForValue().get(key);
                if (o1 == null) {
                    System.out.println(Thread.currentThread().getName());
                    Integer random = (int) (Math.random() * 1000);
                    System.out.println("...getdata " + random);
                    redisTemplate.opsForValue().set(key, String.valueOf(random));
                    return String.valueOf(random);
                } else {
                    return o1.toString();
                }
            }
        }
        return o.toString();
    }

    @ApiOperation(value = "描述value :c测试redis increment", notes = "描述notes  redis increment", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, extensions = {
            @Extension(name = "version", properties = @ExtensionProperty(name = "since", value = "4.0"))})
    @RequestMapping(value = "/desc", method = RequestMethod.GET)
    public String home() {
        redisTemplate.delete("test:incre");
        for (int i = 0; i < 500; i++) {
            String key = String.format("test:incre");
            Long max = redisTemplate.opsForValue().increment(key, 1L);
            if (max == 0L) max++;
            if (max % 127 == 0) {
                max = redisTemplate.opsForValue().increment(key, 1L);
            }
            Long cameraId = max % 127;
            Long regionId = max / 127 + 1;
            System.out.println(regionId + "," + cameraId);
        }
        return "Hello World!";
    }

    @GetMapping("/testEnum")
    public Object testEnum() {
        List list = redisTemplate.opsForValue().multiGet(Lists.newArrayList("Whale:Camera:License:face_max_num", "Whale:Camera:License:face_pedestrian_max_num",
                "Whale:Camera:License:video_struct_max_num", "aaa"));
        return list;
    }

    @GetMapping("/getLock/{cacheKey}")
    public boolean getLock(@PathVariable String cacheKey) {
        logger.info("getLock: {}", cacheKey);
        Boolean acquire = redissonLockUtil.acquire(cacheKey, TimeUnit.SECONDS, 2, 20);
        return acquire;
    }

    @GetMapping("/findCountry/{code}")
    public Country findCountryByName(@PathVariable String code) {
        logger.info("input param code：{}", code);
        return null;
    }

    @GetMapping("/findUserByName")
    public User findUserByName(@RequestParam String name) {
        logger.info("input param name：{}", name);
        return userService.findUserByName(name);
    }

    @GetMapping("/updateUser")
    public User updateUser(@RequestParam String name) {
//        return userService.udpateByUser();
        return null;
    }

    @GetMapping("/findUserById")
    public User findUserById(@RequestParam String id) {
        logger.info("input param id：{}", id);
        return userService.findUserById(Long.valueOf(id));
    }

    @GetMapping("/findUserById2")
    public User findUserById2(@RequestParam String id) {
        logger.info("input param id：{}", id);
        return userService.findUserById2(Long.valueOf(id));
    }

    @PostMapping("/test")
    public User updateUserByExample(@RequestBody User user) {
        return userService.updateUser(user);
    }

    @PostMapping("/updateCountry")
    public int updateCountryByExample(@RequestBody Country c) {
        return 0;
    }

    @GetMapping("/getsql")
    public String getsql() {
        VideoResource videoResource = videoResourceMapper.selectByPrimaryKey(100001L);
//        Configuration configuration = sqlSessionFactory.getConfiguration();
//
//        MappedStatement s = configuration.getMappedStatement("com.sensetime.iva.whale.video.core.dao.VideoResourceMapper.test");
//        Map<String, Object> paramMap = new HashMap();
//        paramMap.put("list", Lists.newArrayList("1", "2"));
//        BoundSql bSql = s.getBoundSql(paramMap);
//        //获取到sql中封装的参数的数量
//        List<ParameterMapping> paramValues = bSql.getParameterMappings();
//        String sql = getExecuteSql(bSql.getSql(), paramValues, paramMap);
        List<TimeRange> timeRanges = Lists.newArrayList();
        TimeRange t1 = new TimeRange();
        t1.setStartTime(1L);
        t1.setEndTime(11L);
        TimeRange t2 = new TimeRange();
        t2.setStartTime(2L);
        t2.setEndTime(22L);
        timeRanges.add(t1);
        timeRanges.add(t2);
        TimeSlot timeSlot = new TimeSlot();
        timeSlot.setTimeStart("00:00:00");
        timeSlot.setTimeEnd("12:00:00");
        List<TimeSlot> timeSlots = Lists.newArrayList(timeSlot);
        String sql = SqlHelper.getMapperSql(videoResourceMapper, "test", "bitmap", timeRanges, null, "entity");
        System.out.println(sql);
        return sql;
    }

    /**
     * 生成可执行sql
     *
     * @param sql         获取的sql
     * @param paramValues 动态参key
     * @param map         动态参valur
     * @return
     */
    private String getExecuteSql(String sql, List<ParameterMapping> paramValues, Map map) {
        while (sql.indexOf("?") != -1 && paramValues.size() > 0) {
            String paramName = paramValues.get(0).getProperty();
            String paramValue = map.get(paramName).toString();
            String value = "";
            if (paramValue instanceof String) {
                value = "'" + paramValue + "'";
            }
            sql = sql.replaceFirst("\\?", value);
            paramValues.remove(0);
        }
        return sql;
    }
}
